
package com.ffcs.crmd.tsp.admin.facade.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ctg.itrdc.platform.common.entity.PageInfo;
import com.ctg.itrdc.platform.common.utils.bean.BeanUtils;
import com.ffcs.crmd.platform.core.ddd.facade.impl.AbstractCrmDomFacade;
import com.ffcs.crmd.tsp.admin.api.dto.JobDetailDTO;
import com.ffcs.crmd.tsp.admin.api.dto.JobDetailRetryDTO;
import com.ffcs.crmd.tsp.admin.api.dto.JobDetailRunningDTO;
import com.ffcs.crmd.tsp.admin.api.dto.JobDetailThreadInfoDTO;
import com.ffcs.crmd.tsp.admin.api.dto.ThreadInfoDTO;
import com.ffcs.crmd.tsp.admin.api.facade.IJobDetailFacade;
import com.ffcs.crmd.tsp.admin.entity.JobDetail;
import com.ffcs.crmd.tsp.admin.entity.JobDetailParam;
import com.ffcs.crmd.tsp.admin.entity.JobDetailRetry;
import com.ffcs.crmd.tsp.admin.entity.JobDetailRunning;
import com.ffcs.crmd.tsp.admin.entity.JobDetailThreadInfo;
import com.ffcs.crmd.tsp.admin.entity.Slice;
import com.ffcs.crmd.tsp.admin.entity.SliceGroup;
import com.ffcs.crmd.tsp.admin.service.IJobDetailService;
import com.ffcs.crmd.tsp.admin.service.ISliceGroupService;
import com.ffcs.crmd.tsp.admin.service.ISliceService;
import com.ffcs.crmd.tsp.common.constant.TspAppConstant;
import com.ffcs.crmd.tsp.common.exception.TspException;

@Service("jobDetailFacade")
public class JobDetailFacadeImpl extends AbstractCrmDomFacade implements IJobDetailFacade {
    
    @Autowired
    private IJobDetailService  jobDetailService;
    
    @Autowired
    private ISliceGroupService sliceGroupService;
    
    @Autowired
    private ISliceService      sliceService;
    
    private PageInfo<JobDetailDTO> copyPageInfo(PageInfo<JobDetail> pageInfo) throws Exception {
        PageInfo<JobDetailDTO> pageInfoDto = new PageInfo<JobDetailDTO>();
        BeanUtils.applyIf(pageInfoDto, pageInfo, false);
        pageInfoDto.setList(BeanUtils.copyList(pageInfo.getList(), JobDetailDTO.class));
        return pageInfoDto;
    }
    
    @Override
    public JobDetailDTO get(JobDetailDTO jobDetailDto) throws Exception {
        JobDetail jobDetail = new JobDetail();
        BeanUtils.applyIf(jobDetail, jobDetailDto, false);
        
        JobDetailDTO rjobDetailDto = new JobDetailDTO();
        JobDetail rjobDetail = jobDetailService.get(jobDetail);
        BeanUtils.applyIf(rjobDetailDto, rjobDetail, false);
        return rjobDetailDto;
    }
    
    @Override
    public void finish(JobDetailRunningDTO jobDetailRunningDto) throws Exception {
        JobDetailRunning jobDetailRunning = new JobDetailRunning();
        BeanUtils.applyIf(jobDetailRunning, jobDetailRunningDto, false);
        jobDetailService.finish(jobDetailRunning);
    }
    
    @Override
    public void finish(List<JobDetailRunningDTO> jobDetailRunningDtoList) throws Exception {
        List<JobDetailRunning> jobDetailRunningList = BeanUtils.copyList(jobDetailRunningDtoList, JobDetailRunning.class);
        jobDetailService.finish(jobDetailRunningList);
    }
    
    @Override
    public void interrupt(JobDetailRunningDTO jobDetailRunningDto) throws Exception {
        JobDetailRunning jobDetailRunning = new JobDetailRunning();
        BeanUtils.applyIf(jobDetailRunning, jobDetailRunningDto, false);
        jobDetailService.interrupt(jobDetailRunning);
    }
    
    @Override
    public void interrupt(List<JobDetailRunningDTO> jobDetailRunningDtoList) throws Exception {
        List<JobDetailRunning> jobDetailRunningList = BeanUtils.copyList(jobDetailRunningDtoList, JobDetailRunning.class);
        jobDetailService.interrupt(jobDetailRunningList);
    }
    
    @Override
    public void pause(JobDetailDTO jobDetailDto) throws Exception {
        JobDetail jobDetail = new JobDetail();
        BeanUtils.applyIf(jobDetail, jobDetailDto, false);
        jobDetailService.pasueJobDetail(jobDetail);
    }
    
    @Override
    public void pause(List<JobDetailDTO> jobDetailDtoList) throws Exception {
        List<JobDetail> jobDetailList = BeanUtils.copyList(jobDetailDtoList, JobDetail.class);
        jobDetailService.pasueJobDetail(jobDetailList);
    }
    
    @Override
    public PageInfo<JobDetailDTO> queryPage(JobDetailDTO jobDetailDTO) throws Exception {
        JobDetail jobDetail = new JobDetail();
        BeanUtils.applyIf(jobDetail, jobDetailDTO, false);
        
        PageInfo<JobDetail> pageInfo = jobDetailService.queryPage(jobDetail, jobDetailDTO.getPageNumber(), jobDetailDTO.getPageSize());
        return copyPageInfo(pageInfo);
    }
    
    @Override
    public PageInfo<JobDetailRetryDTO> queryRetryPage(JobDetailRetryDTO jobDetailRetryDTO) throws Exception {
        JobDetailRetry jobDetailRetry = new JobDetailRetry();
        BeanUtils.applyIf(jobDetailRetry, jobDetailRetryDTO, false);
        
        
        PageInfo<JobDetailRetry> pageInfo = jobDetailService.queryRetryPage(jobDetailRetry, jobDetailRetryDTO.getPageNumber(), jobDetailRetryDTO.getPageSize());
        PageInfo<JobDetailRetryDTO> pageInfoDto = new PageInfo<JobDetailRetryDTO>();
        BeanUtils.applyIf(pageInfoDto, pageInfo, false);
        pageInfoDto.setList(BeanUtils.copyList(pageInfo.getList(), JobDetailRetryDTO.class));
        return pageInfoDto;
    }
    
    @Override
    public PageInfo<JobDetailRunningDTO> queryRunningPage(JobDetailRunningDTO jobDetailRunningDto) throws Exception {
        JobDetailRunning jobDetailRunning = new JobDetailRunning();
        BeanUtils.applyIf(jobDetailRunning, jobDetailRunningDto, false);
        
        PageInfo<JobDetailRunning> pageInfo = jobDetailService.queryRunningPage(jobDetailRunning, jobDetailRunningDto.getPageNumber(), jobDetailRunningDto.getPageSize());
        PageInfo<JobDetailRunningDTO> pageInfoDto = new PageInfo<JobDetailRunningDTO>();
        BeanUtils.applyIf(pageInfoDto, pageInfo, false);
        pageInfoDto.setList(BeanUtils.copyList(pageInfo.getList(), JobDetailRunningDTO.class));
        return pageInfoDto;
    }
    
    @Override
    public JobDetailThreadInfoDTO queryThreadInfo(JobDetailRunningDTO jobDetailRunningDto) throws Exception {
        JobDetailRunning jobDetailRunning = new JobDetailRunning();
        BeanUtils.applyIf(jobDetailRunning, jobDetailRunningDto, false);
        
        JobDetailThreadInfo jobDetailThreadInfo = jobDetailService.queryThreadInfo(jobDetailRunning);
        JobDetailThreadInfoDTO jobDetailThreadInfoDTO = new JobDetailThreadInfoDTO();
        if (jobDetailThreadInfo.getJobProcessThread() != null) {
            BeanUtils.applyIf(jobDetailThreadInfoDTO.getJobProcessThread(), jobDetailThreadInfo.getJobProcessThread(), false);
        }
        
        if (CollectionUtils.isNotEmpty(jobDetailThreadInfo.getJobProcessBusinessThread())) {
            List<ThreadInfoDTO> jobProcessBusinessThread = BeanUtils.copyList(jobDetailThreadInfo.getJobProcessBusinessThread(),
                ThreadInfoDTO.class);
            jobDetailThreadInfoDTO.setJobProcessBusinessThread(jobProcessBusinessThread);
        }
        return jobDetailThreadInfoDTO;
    }
    
    @Override
    public void remove(JobDetailDTO jobDetailDto) throws Exception {
        JobDetail jobDetail = new JobDetail();
        BeanUtils.applyIf(jobDetail, jobDetailDto, false);
        jobDetailService.deleteJobDetail(jobDetail);
    }
    
    @Override
    public void remove(List<JobDetailDTO> jobDetailDtoList) throws Exception {
        List<JobDetail> jobDetailList = BeanUtils.copyList(jobDetailDtoList, JobDetail.class);
        jobDetailService.deleteJobDetail(jobDetailList);
    }
    
    @Override
    public void reset(JobDetailRunningDTO jobDetailRunningDto) throws Exception {
        JobDetailRunning jobDetailRunning = new JobDetailRunning();
        BeanUtils.applyIf(jobDetailRunning, jobDetailRunningDto, false);
        jobDetailService.reset(jobDetailRunning);
    }
    
    @Override
    public void reset(List<JobDetailRunningDTO> jobDetailRunningDtoList) throws Exception {
        List<JobDetailRunning> jobDetailRunningList = BeanUtils.copyList(jobDetailRunningDtoList, JobDetailRunning.class);
        jobDetailService.reset(jobDetailRunningList);
    }
    
    @Override
    public void resume(JobDetailDTO jobDetailDto) throws Exception {
        JobDetail jobDetail = new JobDetail();
        BeanUtils.applyIf(jobDetail, jobDetailDto, false);
        jobDetailService.resumeJobDetail(jobDetail);
    }
    
    @Override
    public void resume(List<JobDetailDTO> jobDetailDtoList) throws Exception {
        List<JobDetail> jobDetailList = BeanUtils.copyList(jobDetailDtoList, JobDetail.class);
        jobDetailService.resumeJobDetail(jobDetailList);
    }
    
    @Override
    public void save(JobDetailDTO jobDetailDto) throws Exception {
        List<JobDetail> jobDetailList = new ArrayList<JobDetail>();
        switch (jobDetailDto.getJobDetailAddType()) {
            case TspAppConstant.TSP_ADD_JOB_DETAIL_BATCH:
                int batchNum = jobDetailDto.getBatchNum();
                for (int i = 0; i < batchNum; i++) {
                    JobDetail jobDetail = new JobDetail();
                    BeanUtils.applyIf(jobDetail, jobDetailDto, false);
                    if (CollectionUtils.isNotEmpty(jobDetailDto.getParams())) {
                        jobDetail.setParams(BeanUtils.copyList(jobDetailDto.getParams(), JobDetailParam.class));
                    } else {
                        jobDetail.setParams(new ArrayList<JobDetailParam>());
                    }
                    
                    jobDetail.setName(jobDetailDto.getName() + (jobDetailDto.getBatchBeginValue() + i));
                    
                    JobDetailParam jobDetailParamTotal = new JobDetailParam();
                    jobDetailParamTotal.setMkey(TspAppConstant.TSP_PARAM_JOB_DETAIL_TOTAL);
                    jobDetailParamTotal.setMvalue(String.valueOf(batchNum));
                    jobDetailParamTotal.setClusterName(jobDetailDto.getClusterName());
                    jobDetail.getParams().add(jobDetailParamTotal);
                    
                    if (jobDetailDto.getModelBeginValue() != null) {
                        JobDetailParam jobDetailParamModelTotal = new JobDetailParam();
                        jobDetailParamModelTotal.setMkey(TspAppConstant.TSP_PARAM_MODEL_TOTAL);
                        jobDetailParamModelTotal.setMvalue(String.valueOf(batchNum));
                        jobDetailParamModelTotal.setClusterName(jobDetailDto.getClusterName());
                        jobDetail.getParams().add(jobDetailParamModelTotal);
                        
                        JobDetailParam jobDetailParamModelValue = new JobDetailParam();
                        jobDetailParamModelValue.setMkey(TspAppConstant.TSP_PARAM_MODEL_VALUE);
                        jobDetailParamModelValue.setMvalue(String.valueOf(jobDetailDto.getModelBeginValue() + i));
                        jobDetailParamModelValue.setClusterName(jobDetailDto.getClusterName());
                        jobDetail.getParams().add(jobDetailParamModelValue);
                    }
                    jobDetailList.add(jobDetail);
                }
                jobDetailService.addJobDetail(jobDetailList);
                break;
            case TspAppConstant.TSP_ADD_JOB_DETAIL_SLICE_BATCH:
                SliceGroup sliceGroupParam = new SliceGroup();
                sliceGroupParam.setClusterName(jobDetailDto.getClusterName());
                sliceGroupParam.setJobId(jobDetailDto.getJobId());
                
                List<SliceGroup> sliceGroupList = sliceGroupService.query(sliceGroupParam);
                if (CollectionUtils.isEmpty(sliceGroupList)) {
                    throw new TspException("该任务没有配置分片组");
                }
                int modelNum = jobDetailDto.getModelNum();
                int sliceGroupNum = sliceGroupList.size();
                for (int i = 0; i < modelNum; i++) {
                    for (int j = 0; j < sliceGroupNum; j++) {
                        SliceGroup sliceGroup = sliceGroupList.get(j);
                        
                        Slice sliceParam = new Slice();
                        sliceParam.setClusterName(jobDetailDto.getClusterName());
                        sliceParam.setSliceGroupId(sliceGroup.getId());
                        List<Slice> sliceList = sliceService.query(sliceParam);
                        
                        JobDetail jobDetail = new JobDetail();
                        BeanUtils.applyIf(jobDetail, jobDetailDto, false);
                        if (CollectionUtils.isNotEmpty(jobDetailDto.getParams())) {
                            jobDetail.setParams(BeanUtils.copyList(jobDetailDto.getParams(), JobDetailParam.class));
                        } else {
                            jobDetail.setParams(new ArrayList<JobDetailParam>());
                        }
                        
                        jobDetail.setName(jobDetailDto.getName() + (jobDetailDto.getBatchBeginValue() + i * sliceGroupNum + j));
                        
                        JobDetailParam jobDetailParamTotal = new JobDetailParam();
                        jobDetailParamTotal.setMkey(TspAppConstant.TSP_PARAM_JOB_DETAIL_TOTAL);
                        jobDetailParamTotal.setMvalue(String.valueOf(modelNum * sliceGroupNum));
                        jobDetail.getParams().add(jobDetailParamTotal);
                        
                        JobDetailParam jobDetailParamModelTotal = new JobDetailParam();
                        jobDetailParamModelTotal.setMkey(TspAppConstant.TSP_PARAM_MODEL_TOTAL);
                        jobDetailParamModelTotal.setMvalue(String.valueOf(modelNum));
                        jobDetailParamModelTotal.setClusterName(jobDetailDto.getClusterName());
                        jobDetail.getParams().add(jobDetailParamModelTotal);
                        
                        JobDetailParam jobDetailParamModelValue = new JobDetailParam();
                        jobDetailParamModelValue.setMkey(TspAppConstant.TSP_PARAM_MODEL_VALUE);
                        jobDetailParamModelValue.setMvalue(String.valueOf(jobDetailDto.getModelBeginValue() + i));
                        jobDetailParamModelValue.setClusterName(jobDetailDto.getClusterName());
                        jobDetail.getParams().add(jobDetailParamModelValue);
                        
                        JobDetailParam jobDetailParamSlices = new JobDetailParam();
                        jobDetailParamSlices.setMkey(TspAppConstant.TSP_PARAM_SLICES);
                        jobDetailParamSlices.setMvalue(sliceToString(sliceList));
                        jobDetailParamSlices.setClusterName(jobDetailDto.getClusterName());
                        jobDetail.getParams().add(jobDetailParamSlices);
                        
                        JobDetailParam jobDetailParamSliceGroupName = new JobDetailParam();
                        jobDetailParamSliceGroupName.setMkey(TspAppConstant.TSP_PARAM_SLICES_GROUP);
                        jobDetailParamSliceGroupName.setMvalue(sliceGroup.getName());
                        jobDetailParamSliceGroupName.setClusterName(jobDetailDto.getClusterName());
                        jobDetail.getParams().add(jobDetailParamSliceGroupName);
                        
                        jobDetailList.add(jobDetail);
                    }
                }
                jobDetailService.addJobDetail(jobDetailList);
                break;
            case TspAppConstant.TSP_ADD_JOB_DETAIL_ALONE:
                JobDetail jobDetail = new JobDetail();
                BeanUtils.applyIf(jobDetail, jobDetailDto, false);
                if (CollectionUtils.isNotEmpty(jobDetailDto.getParams())) {
                    jobDetail.setParams(BeanUtils.copyList(jobDetailDto.getParams(), JobDetailParam.class));
                } else {
                    jobDetail.setParams(new ArrayList<JobDetailParam>());
                }
                
                JobDetailParam jobDetailParamModelTotal = new JobDetailParam();
                jobDetailParamModelTotal.setMkey(TspAppConstant.TSP_PARAM_MODEL_TOTAL);
                jobDetailParamModelTotal.setMvalue(String.valueOf(1));
                jobDetailParamModelTotal.setClusterName(jobDetailDto.getClusterName());
                jobDetail.getParams().add(jobDetailParamModelTotal);
                
                if (jobDetailDto.getModelValue() != null) {
                    JobDetailParam jobDetailParamModelValue = new JobDetailParam();
                    jobDetailParamModelValue.setMkey(TspAppConstant.TSP_PARAM_MODEL_VALUE);
                    jobDetailParamModelValue.setMvalue(String.valueOf(jobDetailDto.getModelValue()));
                    jobDetailParamModelValue.setClusterName(jobDetailDto.getClusterName());
                    jobDetail.getParams().add(jobDetailParamModelValue);
                }
                
                jobDetailService.addJobDetail(jobDetail);
                break;
        }
    }
    
    /**
     * 
     * 功能说明:转换List分片键为String类型
     * 
     * @author ZHONGFUHUA
     *
     * @Date 2016年4月16日
     *
     */
    private String sliceToString(List<Slice> sliceList) {
        String slices = "";
        if (CollectionUtils.isNotEmpty(sliceList)) {
            for (Slice slice : sliceList) {
                slices += slice.getSkey() + ",";
            }
            slices = slices.substring(0, slices.length() - 1);
        }
        return slices;
    }
    
}
